#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <time.h>

using namespace std;

// bounding box in a frame
struct bbox {
	double val[5];
};

struct neighbor{
	vector<int> inds, ovs;
};

// detection result array
struct dres {
	double *x, *y, *w, *h, *r;
	int *fr;
	neighbor *nei;
	int nFrame, nBox;
	
	vector<double> min_cs;
	
	double *c, *dp_c;
	int *dp_link, *orig, *id;
};


struct ores {
	double *ov, *ov_n1, *ov_n2;
	int size;
};

ores calc_overlap(const dres &dres1, int f1i, const dres &dres2,
	int* f2, int nf2);

vector<int> nms_aggressive(dres dres_in, vector<int> inds, double thr_nms);
int find_memberidx(int* a, int na, vector<int> b, int* idx);
int setdiff(int* a, int na, vector<int> b);
dres build_graph(dres dres_in);
dres tracking_dp(dres dres_in, double c_en, double c_ex, double c_ij, double betta, double thr_cost, int max_it, int nms_in_loop);
dres bboxes2dres(vector<vector<bbox>> bboxes);

#define C_EN 10
#define C_EX 10
#define C_IJ 0
#define BETTA 0.2
#define MAX_IT 99999999
#define THR_COST 18